﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Collections.Generic;
using System.Collections.Specialized;

public partial class RuleDefinition : System.Web.UI.Page
{
    #region screen enable/disable/load
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ManageEditable(false);
            if (LBRule.SelectedIndex < 0) BEdit.Visible = false;
        }
    }

    protected void ManageEditable(bool editable)
    {
        PanelMiddle.Enabled = editable;
        PanelUpper.Enabled = editable;
        //manage buttons
        BApply.Visible = editable;
        BCancel.Visible = editable;
        BEdit.Visible = !editable;
        BCreate.Visible = !editable;
        LBAllRules.Enabled = editable;
        LBSelected.Enabled = editable;

        //disable the subrule control
        if (editable)
        {
            LBAllRules.Attributes.Remove("disabled");
            LBSelected.Attributes.Remove("disabled");
        }
        else
        {
            LBAllRules.Attributes.Add("disabled", "");
            LBSelected.Attributes.Add("disabled", "");
        }
    }

    protected void DDLFrequency_Load(object sender, EventArgs e)
    {
        for (int i = 1; i <= 31; i++)
        {
            DDLFrequency.Items.Add(new ListItem(i.ToString(), i.ToString()));
        }
        if (!IsPostBack)
            DDLFrequency.SelectedIndex = 0;
    }

    protected void CBRepeats_CheckedChanged(object sender, EventArgs e)
    {
        DDLFrequency.Enabled = !DDLFrequency.Enabled;
        DDLFreqType.Enabled = !DDLFreqType.Enabled;
        //LabelEvery.ForeColor = DDLFreqType.Enabled ? System.Drawing.Color.Black : System.Drawing.Color.Gray;
        //CBRepeats.ForeColor = DDLFreqType.Enabled ? System.Drawing.Color.Black : System.Drawing.Color.Gray;
    }
    #endregion

    #region buttons at work
    protected void BCancel_Click(object sender, EventArgs e)
    {
        ManageEditable(false);
        if (LBRule.SelectedValue != null)
            loadRule2Panel(Convert.ToInt32(LBRule.SelectedValue.ToString()));
    }

    protected void BEdit_Click(object sender, EventArgs e)
    {
        ManageEditable(true);
    }

    protected void BCreate_Click(object sender, EventArgs e)
    {
        ViewState["SelectedRule"] = null;
        ManageEditable(true);
        LoadDefaultRule2Panel();
    }

    protected void BApply_Click(object sender, EventArgs e)
    {
        //validate
        if (!arePageElementsValid()) return;

        //perform db operation
        int RuleId = -1;
        if (ViewState["SelectedRule"] == null)
            RuleId = updateRulesTable("INSERT", -1);
        else
            RuleId = updateRulesTable("UPDATE", Convert.ToInt32(LBRule.SelectedValue.ToString()));

        //update other tables
        InsertSubRules(RuleId); //rules relations
        InsertCycles(RuleId); //cycles
        LBRule.DataBind();
        LBRule.SelectedValue = RuleId.ToString();
        loadRule2Panel(RuleId);

        //manage display
        ManageEditable(false);
    }
    #endregion

    #region validations
    protected bool arePageElementsValid()
    {
        //check subrules selected
        if (LBSelected.Items.Count <= 0)
        {
            Logger.Show("Please select atleast 1 SubRule.");
            return false;
        }

        //check if any element is empty
        if (String.IsNullOrWhiteSpace(TBRuleName.Text) || String.IsNullOrWhiteSpace(TBRuleName.Text) || String.IsNullOrWhiteSpace(TBRuleName.Text))
        {
            Logger.Show(Logger.MANDATORY_FIELD);
            return false;
        }

        return true;
    }

    protected void TBRuleName_TextChanged(object sender, EventArgs e)
    {
        String mode = "update"; if (ViewState["SelectedRule"] == null) mode = "create";
        if (!GenericValidations.isValidName(TBRuleName.Text, LBRule.Items, mode))
            TBRuleName.Text = String.Empty;
        return;
    }

    protected void TBFromDate_TextChanged(object sender, EventArgs e)
    {
        //check date & also range
        if (!GenericValidations.validateFromToDates(TBFromDate.Text, TBToDate.Text))
            TBFromDate.Text = String.Empty;
        return;
    }

    protected void TBToDate_TextChanged(object sender, EventArgs e)
    {
        //check date & also range
        if (!GenericValidations.validateFromToDates(TBFromDate.Text, TBToDate.Text))
            TBToDate.Text = String.Empty;
        return;
    }
    #endregion

    #region DB operations(cycle/subrules)
    private void InsertCycles(int RuleId)
    {
        DateTime start = Convert.ToDateTime(TBFromDate.Text);
        DateTime end = Convert.ToDateTime(TBToDate.Text);

        //delete old entries before inserting new
        string deleteq = "DELETE FROM CycleStatus WHERE RuleId='" + RuleId.ToString() + "'";
        DataBaseMethods.ExecuteNonQuery(deleteq);

        //add new entries, multiple if checked
        if (CBRepeats.Checked)
        {
            string frequencyType = DDLFreqType.SelectedValue.ToString();
            int frequency = Convert.ToInt32(DDLFrequency.SelectedValue.ToString());

            DateTime current = start;
            DateTime next = getNextCycle(current, frequencyType, frequency);

            int count = 0;
            while (next <= end)
            {
                NameValueCollection nvc = new NameValueCollection();
                nvc.Add("RuleId", RuleId.ToString());
                nvc.Add("CycleId", count.ToString());
                nvc.Add("StartDate", current.ToString("yyyy-MM-dd"));
                nvc.Add("EndDate", next.ToString("yyyy-MM-dd"));
                nvc.Add("Status", "Unbilled");
                String query = DataBaseMethods.generateInsertQuery("CycleStatus", nvc);
                DataBaseMethods.ExecuteNonQuery(query);

                count = count + 1; current = next.AddDays(1);
                next = getNextCycle(current, frequencyType, frequency);
            }
        }
        else
        {
            NameValueCollection nvc = new NameValueCollection();
            nvc.Add("RuleId", RuleId.ToString());
            nvc.Add("CycleId", "0");
            nvc.Add("StartDate", start.ToString("yyyy-MM-dd"));
            nvc.Add("EndDate", end.ToString("yyyy-MM-dd"));
            nvc.Add("Status", "Unbilled");
            String query = DataBaseMethods.generateInsertQuery("CycleStatus", nvc);
            DataBaseMethods.ExecuteNonQuery(query);
        }
    }

    private DateTime getNextCycle(DateTime current, string type, int count)
    {
        DateTime daten = new DateTime();
        if (type == "Days")
            daten = current.AddDays(count).AddDays(-1);
        else if (type == "Weeks")
            daten = current.AddDays(7 * count).AddDays(-1);
        else if (type == "Month")
            daten = current.AddMonths(count).AddDays(-1);
        else
            daten = current.AddYears(count).AddDays(-1);
        return daten;
    }

    private void InsertSubRules(int RuleId)
    {
        //delete old entries
        string query = "DELETE FROM RuleRelations WHERE RuleID='" + RuleId.ToString() + "'";
        DataBaseMethods.ExecuteNonQuery(query);

        //create new entries
        for (int i = 0; i < LBSelected.Items.Count; i++)
        {
            NameValueCollection nvc = new NameValueCollection();
            nvc.Add("RuleId", RuleId.ToString());
            nvc.Add("SubRuleId", LBSelected.Items[i].Value.ToString());
            nvc.Add("Priority", i.ToString());

            string insert = DataBaseMethods.generateInsertQuery("RuleRelations", nvc);
            DataBaseMethods.ExecuteNonQuery(insert);
        }
    }

    private int updateRulesTable(string type, int ruleId)
    {
        NameValueCollection nvc = new NameValueCollection();
        nvc.Add("Name", TBRuleName.Text);
        nvc.Add("FromDate", Convert.ToDateTime(TBFromDate.Text).ToString("yyyy-MM-dd"));
        nvc.Add("ToDate", Convert.ToDateTime(TBToDate.Text).ToString("yyyy-MM-dd"));
        nvc.Add("Repeats", CBRepeats.Checked.ToString());
        if (CBRepeats.Checked)
        {
            nvc.Add("DMY", DDLFreqType.SelectedValue.ToString());
            nvc.Add("DMYCount", DDLFrequency.SelectedValue.ToString());
        }
        nvc.Add("CreatedBy", GlobalVariables.loginId);
        nvc.Add("CreatedOn", DateTime.Now.ToString());

        if (type.Equals("INSERT"))
        {
            string insertQuery = DataBaseMethods.generateInsertQuery("RuleDetails", nvc);
            ruleId = DataBaseMethods.ExecuteIdentityInsert(insertQuery, "RuleId");
        }
        else if (type.Equals("UPDATE"))
        {
            //set primary key
            List<string> key = new List<String> { "RowNo" };
            nvc.Add("RowNo", ruleId.ToString());

            string updateQuery = DataBaseMethods.generateUpdateQuery("RuleDetails", nvc, key);
            DataBaseMethods.ExecuteNonQuery(updateQuery);
        }

        return ruleId;
    }
    #endregion

    #region update display as per selected rule
    protected void LBRule_SelectedIndexChanged(object sender, EventArgs e)
    {
        loadRule2Panel(Convert.ToInt32(LBRule.SelectedValue.ToString()));
        ManageEditable(false);
    }

    void LoadDefaultRule2Panel()
    {
        TBRuleName.Text = String.Empty;
        CBRepeats.Checked = true;
        DDLFreqType.SelectedValue = "Month";
        DDLFrequency.SelectedValue = "1";
        LBSelected.Items.Clear();
    }

    void loadRule2Panel(int RuleId)
    {
        //formulate query
        ViewState["SelectedRule"] = RuleId.ToString(); ;
        string select = "select [Name],[FromDate],[ToDate],[Repeats],[DMY],[DMYCount] From [RuleDetails] where [RowNo] = '" + RuleId.ToString() + "'";

        //retrieve rule details, only one entry
        DataTable datatable = DataBaseMethods.ExecuteSelectQuery(select);
        if (datatable.Rows.Count != 1)
        {
            Logger.Show("Selected RuleId does not exist: " + RuleId + ". ");
            return;
        }
        DataRow datarow = datatable.Rows[0];

        //set details on screen
        TBRuleName.Text = datarow["Name"].ToString();
        TBFromDate.Text = Convert.ToDateTime(datarow["FromDate"].ToString()).ToString("dd-MM-yyyy");
        TBToDate.Text = Convert.ToDateTime(datarow["ToDate"].ToString()).ToString("dd-MM-yyyy");
        CBRepeats.Checked = Convert.ToBoolean(datarow["Repeats"].ToString());
        if (CBRepeats.Checked)
        {
            DDLFreqType.SelectedValue = datarow["DMY"].ToString();
            DDLFrequency.SelectedValue = datarow["DMYCount"].ToString();
        }

        //load selected sub rules
        LBSelected.DataBind();
    }
    #endregion

    #region arrow buttons operations (up, down, right, left)
    protected void IBRight_Click(object sender, ImageClickEventArgs e)
    {
        if (LBAllRules.SelectedIndex < 0) return;
        if (LBSelected.Items.Contains(LBAllRules.SelectedItem)) return;
        ListItem lt = LBAllRules.SelectedItem;
        LBSelected.ClearSelection();
        LBAllRules.ClearSelection();
        LBSelected.Items.Add(lt);
        LBSelected.SelectedValue = lt.Value;
        LBAllRules.Items.Remove(lt);
    }

    protected void IBLeft_Click(object sender, ImageClickEventArgs e)
    {
        if (LBSelected.SelectedIndex < 0) return;
        ListItem lt = LBSelected.SelectedItem;
        LBSelected.ClearSelection();
        LBAllRules.ClearSelection();
        if (!LBAllRules.Items.Contains(lt))
            LBAllRules.Items.Add(lt);
        LBAllRules.SelectedValue = lt.Value;
        LBSelected.Items.Remove(lt);
    }

    protected void IBUp_Click(object sender, ImageClickEventArgs e)
    {
        if (LBSelected.SelectedIndex <= 0) return;
        ListItem li = LBSelected.SelectedItem;
        int index = LBSelected.SelectedIndex;
        LBSelected.Items.Remove(LBSelected.SelectedItem);
        LBSelected.ClearSelection();
        LBSelected.Items.Insert(index - 1, li);
        LBSelected.SelectedIndex = index - 1;
        //LBSelected.a
    }

    protected void IBDown_Click(object sender, ImageClickEventArgs e)
    {
        if (LBSelected.SelectedIndex == (LBSelected.Items.Count - 1)) return;
        ListItem li = LBSelected.SelectedItem;
        int index = LBSelected.SelectedIndex;
        LBSelected.Items.Remove(LBSelected.SelectedItem);
        LBSelected.ClearSelection();
        LBSelected.Items.Insert(index + 1, li);
        LBSelected.SelectedIndex = index + 1;
    }
    #endregion

}